import { MenuData } from "@/api/menu"
import { ITreeItemData } from "@/stores/menu"

export type ITreeItemDataWithMenuData = ITreeItemData & {
  meta?: { icon: string; title: string; [key: string]: string }
}
// 1. 生成内容映射 ts 接口
export type IMap = Record<number, ITreeItemData>

/**
 * generateTree 可以根据远程数据生成权限树、侧边栏的菜单树
 * @param list
 * @param withMeta true 要增加  Meta 数据，用于生成侧边栏用于生成权限菜单。 false 不要增加  Meta 数据，用于菜单编辑页面
 * @returns
 */

// 菜单权限 1. generateTree 函数增加 withMeta 参数
export const generateTree = (list: MenuData[], withMeta: boolean = false) => {
  // 2. 生成内容映射
  const map = list.reduce((memo, current) => {
    const temp = { ...current }
    // 菜单权限 2. withMeta 为true,代表给用后端数据生成的菜单，增加 meta 对象，里面有title 和 icon 属性
    if (withMeta) {
      ;(temp as ITreeItemDataWithMenuData).meta = {
        title: current.title,
        icon: current.icon
      }
    }
    memo[current.id] = temp
    return memo
  }, {} as IMap)
  // 3. 格式化的树
  const tree: ITreeItemDataWithMenuData[] = []
  // 4. 循环遍历 内容映射， 生成树
  list.forEach((item) => {
    // 4-1. 获取父id
    const pid = item.parent_id
    // 4-2 获取map当前项，映射表中的item,才有children属性的，不能用list的item
    const cur = map[item.id]
    // 4-3. 如果有父id
    if (pid !== 0 || pid != null) {
      // 4-4. 获取父级
      const parent = map[pid]
      // 4-5. 判断，父级是否存在
      if (parent) {
        // 4-6. 拿到父的子节点，，映射表中的item,才有children属性的，不能用list的item
        const children = parent?.children || []
        // 4-7.  把当前项，加入父children节点
        children.push(cur)
        // 4-8 .重新赋值子级
        parent.children = children as unknown as ITreeItemDataWithMenuData[]
        return
      }
    }
    // 5. 如果没有父id，直接接加入树
    tree.push(cur)
  })
  return tree
}
